package com.yixia.system.service.impl.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yixia.common.core.domain.TreeSelect;
import com.yixia.common.core.domain.entity.SysArea;
import com.yixia.common.utils.StringUtils;
import com.yixia.system.mapper.system.SysAreaMapper;
import com.yixia.system.service.system.SysAreaService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 35038
* @description 针对表【sys_area】的数据库操作Service实现
* @createDate 2023-06-27 15:47:46
*/
@Service
public class SysAreaServiceImpl extends ServiceImpl<SysAreaMapper, SysArea>
    implements SysAreaService {


    @Autowired
    private SysAreaMapper sysAreaMapper;

    /**
     * 地域生成树
     * @param area
     * @return
     */
    @Override
    public List<TreeSelect> selectAreaTreeList(SysArea area) {

        /*1.先查询到所有的area*/
        List<SysArea> areaList = this.selectSysAreaList(area);
        /*2.对地区数据进行构建使其成为树型结构*/
        List<TreeSelect> treeSelects = buildAreaTreeSelect(areaList);

        return treeSelects;
    }


    @Override
    public List<SysArea> selectSysAreaList(SysArea area)
    {
        QueryWrapper<SysArea> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(area.getAreaId() != null, "area_id", area.getAreaId());
        queryWrapper.eq(area.getParentId() != null, "parent_id", area.getParentId());
        queryWrapper.like(area.getAreaName() != null, "area_name", area.getAreaName());
        queryWrapper.like(area.getShortName() != null, "short_name", area.getShortName());
        queryWrapper.eq(area.getLongitude() != null, "longitude", area.getLongitude());
        queryWrapper.eq(area.getLatitude() != null, "latitude", area.getLatitude());
        queryWrapper.eq(area.getLevel() != null, "level", area.getLevel());
        queryWrapper.eq(area.getSort() != null, "sort", area.getSort());
        queryWrapper.eq(area.getStatus() != null, "status", area.getStatus());
        List<SysArea> sysAreas = sysAreaMapper.selectList(queryWrapper);
        return sysAreas;
    }



    /**
     * 构建前端所需要的树型结构
     * @param areas
     * @return
     */
    public List<TreeSelect> buildAreaTreeSelect(List<SysArea> areas){

        List<SysArea> areaTrees = buildAreaTree(areas);
        return areaTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    private List<SysArea> buildAreaTree(List<SysArea> areas) {
        /*用来装最终的状态*/
        List<SysArea> returnList = new ArrayList<>();
        /*将要构建的树的Id收集起来*/
        List<Long> tempList = areas.stream().map(SysArea::getAreaId).collect(Collectors.toList());
        for(SysArea area : areas){
            /*判断*/
            /*如果顶级节点就将所有的子节点找到*/
            if(!tempList.contains(area.getParentId())){
                /*递归的将节点取出来*/
                recursionFn(areas, area);
                returnList.add(area);
            }
        }
        if(returnList.isEmpty()){
            returnList = areas;
        }
        return returnList;
    }

    /**
     * 递归列表
     * @param list
     * @param d
     * @return
     */
    private void recursionFn(List<SysArea> list, SysArea d){
        //找到该节点的子节点
        List<SysArea> childArea = getChildList(list, d);
        d.setChildren(childArea);
        //对获取到的子节点再次进行遍历
        for (SysArea child : childArea){
            /*再次对子节点进行获取如果长度大于0，说明还有子节点，再次进行递归*/
            if(hasChild(list, child)){
                recursionFn(list, child);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysArea> getChildList(List<SysArea> list, SysArea d){
        List<SysArea> list1 = new ArrayList<>();
        Iterator<SysArea> it = list.iterator();
        while (it.hasNext()) {
            //当数据中的父节点等于顶点节点的id时是该值
            SysArea n = (SysArea) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == d.getAreaId().longValue())
            {
                list1.add(n);
            }
        }
        return list1;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysArea> list, SysArea t)
    {
        return getChildList(list, t).size() > 0;
    }
}




